package ooday04;

import java.util.ArrayList;
import java.util.List;

/** 测试类 */
public class Test {
    public static void main(String[] args) {

        /*
        //向上造型是为了代码复用，此时若还想访问派生类所特有的属性/方法，可以向下转型
        //向下转型的条件:
        //1)引用所指向的对象，就是该类型
        //2)引用所指向的对象，实现了该接口或继承了该类
        Animal o = new Dog("小白",3,"白");
        Dog d = (Dog)o; //引用o的对象就是Dog类型
        Swim s = (Swim)o; //引用o的对象，Dog实现了Swim接口
        //Fish f = (Fish)o; //运行时发生ClassCastException类型转换异常
        //建议：强转前用instance of来判断
        System.out.println(o instanceof Dog); //true
        System.out.println(o instanceof Swim); //true
        System.out.println(o instanceof Fish); //false

        //演示向上造型(多态)的第2点应用
        //将超类型(Animal)作为参数或返回值类型，传递或返回派生类(Dog/Fish/Chick)对象，以扩大方法的的应用范围，实现代码复用
        Master master = new Master();
        Animal dog = new Dog("小白",3,"白"); //向上造型
        Fish fish = new Fish("小金",3,"金");
        Chick chick = new Chick("小黄",3,"黄");
        master.feed(dog);
        master.feed(fish); //在传参的同时，系统自动做了向上造型
        master.feed(chick);
        */

        //演示向上造型(多态)的第1点应用
        //因为数据分装在3个数组中，所以需要3个for循环---重复
        //将不同对象(狗、鱼、鸡)统一封装到一个数组(动物数组)中来访问，实现代码复用
        //Animal o = new Animal(); //抽象类不能被实例化
        Animal[] animals = new Animal[5];
        animals[0] = new Dog("小黑",2,"黑"); //向上造型：超类型引用指向派生类对象
        animals[1] = new Dog("小白",3,"白");
        animals[2] = new Fish("小金",2,"金");
        animals[3] = new Fish("小红",4,"红");
        animals[4] = new Chick("小黄",1,"黄");
        for(int i=0;i<animals.length;i++){ //遍历所有动物
            System.out.println(animals[i].getName()); //输出每个动物的名字
            animals[i].eat(); //每个动物吃饭，能点出什么取决于引用的类型
            animals[i].drink(); //每个动物喝水
            if(animals[i] instanceof Dog){ //若为Dog类型
                Dog dog = (Dog)animals[i]; //向下转型
                dog.lookHome();
            }
            if(animals[i] instanceof Chick){ //若为Chick类型
                Chick chick = (Chick)animals[i]; //向下转型
                chick.layEggs();
            }
            if(animals[i] instanceof Swim){ //若能游泳(实现Swim接口的)
                Swim s = (Swim)animals[i]; //向下转型
                s.swim();
            }
        }

        //向上造型、向下转型的animal的集合版本
        List<Animal> animals1 = new ArrayList<>();
        animals1.add(new Dog("小黑",2,"黑"));
        animals1.add(new Dog("小白",3,"白"));
        animals1.add(new Fish("小金",2,"金"));
        animals1.add(new Chick("小红",4,"红"));
        animals1.add(new Chick("小黄",1,"黄"));
        System.out.println(animals1);
        for(int i=0;i<animals1.size();i++){
            Animal animal = animals1.get(i);
            System.out.println(animal.getName());
            animal.eat();
            animal.drink();
            if(animal instanceof Dog){
                Dog dog = (Dog)animal;
                dog.lookHome();
            }
            if(animal instanceof Chick){
                Chick chick = (Chick)animal;
                chick.layEggs();
            }
            if(animal instanceof Swim){
                Swim s = (Swim)animal;
                s.swim();
            }
        }
    }
}
